import { Provide } from '@midwayjs/decorator';
import { IWebMiddleware } from '@midwayjs/web';
import { Context } from 'egg';
import * as jwt from 'jsonwebtoken';

import { InjectEntityModel } from '@midwayjs/orm';
import { Repository } from 'typeorm';
import { Users } from '../entity/Users';



@Provide()
export class TokenVerifyMiddleware implements IWebMiddleware {

  @InjectEntityModel(Users)
  userModel: Repository<Users>;

  resolve() {
    return async (ctx: Context, next: () => Promise<any>) => {
      // 你可以获取 config 的配置：
      // const config = ctx.app.config;
      // config.xxx....

      //console.log('VERIFY!');
      //console.log(ctx.request.url);

      //console.log(this.options)

      const token = <string>ctx.request.headers.auth;

      //console.log(token);

      if(ctx.request.originalUrl.endsWith('login'))
      {
          await next();
          return
      }

      if (!token) {
        ctx.error(ctx.app.ErrorCode.USER_UNLOGIN);
        return;
      }

      let userInfo: any = {};

      try {
        userInfo = jwt.verify(token, ctx.app.config.token.secretKey);
      } catch (err) {
        ctx.error(ctx.app.ErrorCode.AUTH_INVALID);
        return;
      }

      console.log(userInfo)

      let now = Math.floor(Date.now() / 1000)
      if (!!userInfo.expireTime && userInfo.expireTime < now) {
        ctx.error(ctx.app.ErrorCode.AUTH_EXPIRED);
        return;
      }
      else if (!!userInfo.expireTime && (userInfo.expireTime - now < ctx.app.config.token.duration * 0.4)) {
        //更新头
        const expireTime = now + ctx.app.config.token.duration;
        userInfo.expireTime = expireTime
        const token = jwt.sign(userInfo, ctx.app.config.token.secretKey)
        ctx.res.setHeader('auth', token)
        console.log('更新头')
      }

      let user_id = parseInt(userInfo.user_id)

      if (!userInfo.user_id) {
        ctx.error(ctx.app.ErrorCode.USER_NOT_EXIST);
        return
      }

      //console.log(`user_id:${user_id}`)
      //let user = await ctx.app.model.User.findByPk(user_id)

      let user:Users = await this.userModel.findOneOrFail(user_id)

      if (!user) {
        ctx.error(ctx.app.ErrorCode.USER_NOT_EXIST);
        return
      }

      
      // if (!!options && user.role !== options.role) {
      //   ctx.error(ctx.app.ErrorCode.USER_NOT_EXIST);
      //   return
      // }

      ctx.user = user

      await next();
    };
  }
}